#include "task_modbus.h"
#include "para.h"
#include "user_mb_app_s.h"
#include "FreeRTOS.h"
#include "task.h"
#include "drv_wdt.h"
#include "task_cycle.h"
#include "wireless.h"
#include "app_input.h"
#include "app_can.h"
#include "app_output.h"
#define TASK_PRIO_STACKSIZE_MODBUS 128
static TaskHandle_t task_modbus_handle = NULL;
void Task_mbTcp_master(void);
/**
 * @brief modbus 寄存器数据处理任务初始化，关联底层输入和输出任务
 */
void Task_mbTcp_slave_init(void)
{
    xTaskCreate((TaskFunction_t)Task_mbTcp_master,
                                "task modbus",
                                TASK_PRIO_STACKSIZE_MODBUS,
                                NULL,
                                TASK_PRIO_MBTCP_SLAVE,
                                (TaskHandle_t *)task_modbus_handle); 
}
/**
 * @brief 离散输入数据填充
 */
void discrete_data_handler(void)
{
    ucSDiscInBuf[0] = (gp_io->di[0] <<0) | (gp_io->di[1] <<1) | (gp_io->di[2] <<2) | (gp_io->di[3] <<3) | 
                      (gp_io->di[4] <<4) | (gp_io->di[5] <<5) | (gp_io->di[6] <<6) | (gp_io->di[7] <<7);
    ucSDiscInBuf[1] = (gp_io->di[8] <<0) | (gp_io->di[9] <<1) | (gp_io->di[10]<<2) | (gp_io->di[11]<<3) | 
                      (gp_io->di[12]<<4) | (gp_io->di[13]<<5) | (gp_io->di[14]<<6) | (gp_io->di[15]<<7);
    ucSDiscInBuf[2] = (gp_io->di[16]<<0) | (gp_io->di[17]<<1) | (gp_io->di[18]<<2) | (gp_io->di[19]<<3) | 
                      (gp_io->di[20]<<4) | (gp_io->di[21]<<5) | (gp_io->di[22]<<6) | (gp_io->di[23]<<7);
    ucSDiscInBuf[3] = (gp_io->di[24]<<0) | (gp_io->di[25]<<1) | (gp_io->di[26]<<2) | (gp_io->di[27]<<3) | 
                      (gp_io->di[28]<<4) | (gp_io->di[29]<<5) | (gp_io->di[30]<<6) | (gp_io->di[31]<<7);
    ucSDiscInBuf[4] = (gp_io->di[32]<<0) | (gp_io->di[33]<<1);
}
/**
 * @brief 输入寄存器数据填充
 */
void input_data_handler(void)
{
    uint8_t index = 0;
    for(index = 0; index < HEM_AI_NUM; index++)//ADC 16+2=18
    {
        usSRegInBuf[index] = gp_io->ai[index];
    }
    for(index = 0; index < HEM_PI_NUM; index++)//8 PI
    {
        usSRegInBuf[index + HEM_AI_NUM] = (uint16_t)(gp_io->pi[index]);
    }
    for(index = 0; index < HEM_PWMI_NUM; index++)//12 PWMI
    {
        usSRegInBuf[index + HEM_AI_NUM + HEM_PI_NUM] = gp_io->ai_pwmi[index];
    }
    usSRegInBuf[38] = (gp_io->di[0] <<0)  | (gp_io->di[1] <<1)  | (gp_io->di[2] <<2)  | (gp_io->di[3] <<3) | 
                      (gp_io->di[4] <<4)  | (gp_io->di[5] <<5)  | (gp_io->di[6] <<6)  | (gp_io->di[7] <<7) |
                      (gp_io->di[8] <<8)  | (gp_io->di[9] <<9)  | (gp_io->di[10]<<10) | (gp_io->di[11]<<11)| 
                      (gp_io->di[12]<<12) | (gp_io->di[13]<<13) | (gp_io->di[14]<<14) | (gp_io->di[15]<<15);

    usSRegInBuf[39] = (gp_io->di[16]<<0)  | (gp_io->di[17]<<1)  | (gp_io->di[18]<<2)  | (gp_io->di[19]<<3) | 
                      (gp_io->di[20]<<4)  | (gp_io->di[21]<<5)  | (gp_io->di[22]<<6)  | (gp_io->di[23]<<7) |
                      (gp_io->di[24]<<8)  | (gp_io->di[25]<<9)  | (gp_io->di[26]<<10) | (gp_io->di[27]<<11)| 
                      (gp_io->di[28]<<12) | (gp_io->di[29]<<13) | (gp_io->di[30]<<14) | (gp_io->di[31]<<15);
    usSRegInBuf[40] = (gp_io->di[32]<<0)  | (gp_io->di[33]<<1);
	/*无线接收数据*/	
#if (PROCS_PROTOCOL == 1)
	usSRegInBuf[50] = (uint16_t)ul_rd_rx_cnt;//无线接收字节数
    usSRegInBuf[51] = ub_rd_rx_data.data.head;
    usSRegInBuf[52] = ub_rd_rx_data.data.addr;
    usSRegInBuf[53] = ub_rd_rx_data.data.len;
    usSRegInBuf[54] = ub_rd_rx_data.data.cmd;
    usSRegInBuf[55] = ub_rd_rx_data.data.data[0];
    usSRegInBuf[56] = ub_rd_rx_data.data.data[1];
    usSRegInBuf[57] = ub_rd_rx_data.data.power_voltage;
    
	usSRegInBuf[58] = ub_rd_rx_data.data.rollingCounter;
    
    usSRegInBuf[59] = ub_rd_rx_data.data.power_off_left_timel;
    usSRegInBuf[60] = ub_rd_rx_data.data.power_off_left_timeh;
    usSRegInBuf[61] = ub_rd_rx_data.data.check_sum;
    usSRegInBuf[62] = ub_rd_rx_data.data.tail;
#endif
    usSRegInBuf[63] = SX1278_RLEN;
    usSRegInBuf[64] = (ul_tick_value/2);
    usSRegInBuf[65] = (uc_rd_key01<<0) | (uc_rd_key02<<1) | (uc_rd_key03<<2) | (uc_rd_key04<<3) | 
                      (uc_rd_key05<<4) | (uc_rd_key06<<5) | (uc_rd_key07<<6) | (uc_rd_key08<<7) |
                      (uc_rd_key_emorgency_stop);
    
    //TODO: 其他任务代码...     
}
/**
 * @brief 线圈数据输出
 */
void coils_data_handler(void)
{ 
    uint8_t i = 0;
    for(i = 0;i < HEM_DO_NUM;i++)
    {
        gp_io->dout[i] |= (ucSCoilBuf[i/8]>>(i%8))&0x01;
    }
}
/**
 * @brief 保持寄存器数据输出
 */
void holding_register_handler(void)
{
    uint8_t index = 0;
    /*PWM输出*/
    for(index = 0; index < HEM_PWM_NUM; index++)
    {
        gp_io->pwm[index] = usSRegHoldBuf[index];
    }
    /*PWMI输出*/
    for(index = 0; index < HEM_PWMI_NUM; index++)
    {
       gp_io->pwmi[index] = usSRegHoldBuf[index + HEM_PWM_NUM];
    }
    /*AO输出*/
    for(index = 0; index < HEM_AO_NUM; index++)
    {
        gp_io->ao[index] = usSRegHoldBuf[index + HEM_PWM_NUM + HEM_PWMI_NUM];
    }
    /*DO输出*/
    for(index = 0; index < 16; index++)
    {
        gp_io->dout[index]    = (usSRegHoldBuf[29]>>index)&0x01;
        gp_io->dout[index+16] = (usSRegHoldBuf[30]>>index)&0x01;
    }
    
}
/**
 * @brief 保持寄存器，设置输入端口模式
 */
void holding_register_set_input_mode(void)
{
    uint8_t register_base_address = 64;
    uint8_t index = 0;
    uint8_t value = 0;
    uint8_t uc_set_param_config_changed = 0;

    if(uc_rx_set_parameter_data_flag != 1) return;

    for(index = 0; index < HEM_AI_NUM; index++)
    {
        value = usSRegHoldBuf[register_base_address + index] - 1;
        if((usSRegHoldBuf[register_base_address + index] != 0) && (g_config.in_mode[index] != value))
        {
            g_config.in_mode[index] = value;
            uc_set_param_config_changed = 1;
            if(index < 15)
            {
                //4~20mA,输入端口必须选择0~5V采样
                if(value == 2) g_I0_to_I15_ai_config[index] = 1;
                else g_I0_to_I15_ai_config[index] = 0;
            }
            else if(index == 15)
            {
                if(value == 2) 
                {
                    g_I0_to_I15_ai_config[index] = 1;
                    g_pca9555_port_func[index-15] = 1;
                }
                else if(value == 3)
                {
                    g_I0_to_I15_ai_config[index] = 0;
                    g_pca9555_port_func[index-15] = 0;
                }
                else 
                {
                    g_I0_to_I15_ai_config[index] = 0;
                    g_pca9555_port_func[index-15] = 1;
                }
            }
            if((index >= 16) && (index < 18))
            {
                if(value == 3) g_pca9555_port_func[index-15] = 0;
                else g_pca9555_port_func[index-15] = 1;
            }
            if((index >= 18) && (index < 26))
            {
                if(value == 5) g_DI0_to_DI15_config[index-18] = 1;
                else g_DI0_to_DI15_config[index-18] = 0;
            }
        }
    }
    if (uc_set_param_config_changed == 1) {
        wdt_feed();
        g_config.config_ok = FLASH_CONFIG_OK;
        //hem_config_save(&g_config);
  }
}
/**
 * 输入端口配置参数初始化
 */
void in_parameters_init(void)
{
    uint8_t index = 0;
    uint8_t register_base_address = 64;
    for(index = 0; index < HEM_IN_PORT_NUM; index++)
    {
        usSRegHoldBuf[register_base_address + index] = (uint16_t)(g_config.in_mode[index]);
    }
}
/**
 * @brief 保持寄存器，设置PWM频率
 */
void holding_register_set_pwm_freq(void)
{
    uint8_t register_base_address = 120; 
    uint8_t index = 0;

    if(uc_rx_set_parameter_data_flag != 2) return;
    for(index = 0; index < HEM_PWM_FREQ_NUM; index++)
    {
        if((usSRegHoldBuf[register_base_address + index] > 20) && (usSRegHoldBuf[register_base_address + index] < 60000) && (g_config.pwm_freq[index] != usSRegHoldBuf[register_base_address + index]))
        {
            g_config.pwm_freq[index] = usSRegHoldBuf[register_base_address + index];
            uc_set_param_config_changed = 1;
        }
    }
    if(uc_set_param_config_changed == 1)
    {
        wdt_feed();
        PWM_Init(&g_config.pwm_freq[0],6);
        //hem_config_save(&g_config);
    }
}
/**
 * @brief 保持寄存器，初始化PWM频率
 */
void holding_register_init_pwm_freq(void)
{
    uint8_t register_base_address = 120; 
    uint8_t index = 0;
    for(index = 0; index < HEM_PWM_FREQ_NUM; index++)
    {
        usSRegHoldBuf[register_base_address + index] = (uint16_t)(g_config.pwm_freq[index]);
    }
}
/**
 * @brief modbus TCP设置参数，保持寄存器，设置CAN参数
 */
void holding_register_set_can_para(void)
{
    uint8_t register_base_address = 130;
    if(uc_rx_set_parameter_data_flag != 3) return;
    /*CAN0波特率*/
    if((usSRegHoldBuf[register_base_address+0] >= 125) && (usSRegHoldBuf[register_base_address+0] <= 1000) && (g_config.baudrate[0] != usSRegHoldBuf[register_base_address+0]))
    {
        g_config.baudrate[0] = usSRegHoldBuf[register_base_address+0];
        uc_set_param_config_changed = 1;
    }
    /*CAN1波特率*/
    if((usSRegHoldBuf[register_base_address+1] >= 125) && (usSRegHoldBuf[register_base_address+1] <= 1000) && (g_config.baudrate[1] != usSRegHoldBuf[register_base_address+1]))
    {
        g_config.baudrate[1] = usSRegHoldBuf[register_base_address+1];
        uc_set_param_config_changed = 1;
    }
    /*CAN0终端电阻*/
    if((usSRegHoldBuf[register_base_address+2] >= 1) && (usSRegHoldBuf[register_base_address+2] <= 2))
    {
        if(g_config.can_terminal_resistor[0] != (usSRegHoldBuf[register_base_address+2] - 1)) 
        {
            g_config.can_terminal_resistor[0] = usSRegHoldBuf[register_base_address+2] - 1;
            uc_set_param_config_changed = 1;
        }
    }
    /*CAN1终端电阻*/
    if((usSRegHoldBuf[register_base_address+3] >= 1) && (usSRegHoldBuf[register_base_address+3] <= 2))
    {
        if(g_config.can_terminal_resistor[1] != (usSRegHoldBuf[register_base_address+3] - 1)) 
        {
            g_config.can_terminal_resistor[1] = usSRegHoldBuf[register_base_address+3] - 1;
            uc_set_param_config_changed = 1;
        }
    }
    if(uc_set_param_config_changed == 1)
    {
        wdt_feed();
        //hem_config_save(&g_config);
    }
}

/**
 * @brief 保持寄存器，初始化CAN参数
 */
void holding_register_init_can_para(void)
{
    uint8_t register_base_address = 130;
    usSRegHoldBuf[register_base_address+0] = g_config.baudrate[0];
    usSRegHoldBuf[register_base_address+1] = g_config.baudrate[1];
    usSRegHoldBuf[register_base_address+2] = (g_config.can_terminal_resistor[0] + 1);
    usSRegHoldBuf[register_base_address+3] = (g_config.can_terminal_resistor[1] + 1);
}

/**
 * @brief 保持寄存器，PWMI标定参数设置
 */
void holding_register_set_pwmi_para(void)
{
    uint8_t register_base_address = 140;
    uint8_t index = 0;
    if(uc_rx_set_parameter_data_flag != 4) return;
    for(index = 0; index < HEM_PWMI_NUM; index++)
    {
        if((uc_pwmi_param_buf_200_mA[index] == usSRegHoldBuf[register_base_address + index]) || (usSRegHoldBuf[register_base_address + index] == 0)) continue;
        else 
        {
            uc_pwmi_param_buf_200_mA[index] = usSRegHoldBuf[register_base_address + index];
            g_pwmi_store_param_sn = 1;
        }
    }

    for(index = 0; index < HEM_PWMI_NUM; index++)
    {
        if((uc_pwmi_param_buf_800_mA[index] == usSRegHoldBuf[register_base_address + index + 12]) || (usSRegHoldBuf[register_base_address + index + 12] == 0)) continue;
        else 
        {
            uc_pwmi_param_buf_800_mA[index] = usSRegHoldBuf[register_base_address + index + 12];
            g_pwmi_store_param_sn = 1;
        }
    }

    if(g_pwmi_store_param_sn == 1)
    {
        wdt_feed();
        pwmi_parameter_store();
    }
}
/**
 * @brief 保持寄存器，PWMI标定参数初始化
 */
void holding_register_init_pwmi_para(void)
{
    uint8_t register_base_address = 140;
    uint8_t index = 0;
    for(index = 0; index < HEM_PWMI_NUM; index++)
    {
        usSRegHoldBuf[register_base_address + index]      = uc_pwmi_param_buf_200_mA[index];
        usSRegHoldBuf[register_base_address + index + 12] = uc_pwmi_param_buf_800_mA[index];
    }
}
void holding_register_init_version(void)
{
    uint8_t register_base_address = 190;

    usSRegHoldBuf[register_base_address+0] = (uint16_t)g_year;
    usSRegHoldBuf[register_base_address+1] = (uint16_t)g_month;
    usSRegHoldBuf[register_base_address+2] = (uint16_t)g_day;
    usSRegHoldBuf[register_base_address+3] = (uint16_t)g_hour;
    usSRegHoldBuf[register_base_address+4] = (uint16_t)g_minute;
    usSRegHoldBuf[register_base_address+5] = (uint16_t)g_second;
}
void modbus_tcp_param_init(void)
{
    holding_register_init_pwm_freq();
    holding_register_init_can_para();
    holding_register_init_pwmi_para();
    in_parameters_init();
    holding_register_init_version();
}
uint8_t uc_rx_set_parameter_data_flag = 0;/*modbus tcp 收到设置参数的数据*/
void modbus_tcp_param_save(void)
{
    if(uc_rx_set_parameter_data_flag == 0) return;

    holding_register_set_input_mode();
    holding_register_set_pwm_freq();
    holding_register_set_can_para();
    holding_register_set_pwmi_para();

    uc_rx_set_parameter_data_flag = 0;
}
uint8_t uc_mb_tcp_rx_data_flag = 0;/*modbus tcu接收到数据标志*/
/**
 * @biref modbus tcp数据填充任务
 */
void Task_mbTcp_master(void)
{
    modbus_tcp_param_init();
    while(1)
    {
        if(uc_mb_tcp_rx_data_flag == 1)
        {
            uc_mb_tcp_rx_data_flag = 0;

            discrete_data_handler();
            input_data_handler();
            holding_register_handler();
            holding_register_set_input_mode();
        }
        vTaskDelay(15); 
    }
}





